import scala.collection.mutable.HashMap

import java.util.{EventObject}

package tfd.scala.squib.jmc {

    import com.sun.media.jmc.event.{MediaStateEvent, MediaStateListener, VideoRendererEvent, VideoRendererListener}

    trait FiresMediaStateEvents[T <: {  def addMediaStateListener(cl:MediaStateListener) }] { self:FiresEventObjects with IdableTrait =>
        self.eventHandlers += (mediaStateEvents _).asInstanceOf[(Object, HashMap[String, EventObject => Unit]) => Unit]

        def mediaStateEvents(comp: T, events:HashMap[String, EventObject => Unit]):T = {
            val handler = new DelegateMediaStateHandler(events);
            if (handler.hasEvents) {
                comp.addMediaStateListener(handler)
            }
            comp
        }

        class DelegateMediaStateHandler(events: HashMap[String, EventObject => Unit]) extends MediaStateListener {
            private val endOfMediaReachedDelegate:Option[MediaStateEvent => Unit] = events.get("endofmediareached");
            private val playerStartedDelegate:Option[MediaStateEvent => Unit] = events.get("playerstarted");
            private val playerStoppedDelegate:Option[MediaStateEvent => Unit] = events.get("playerstopped");
            private val playerRepeatedDelegate:Option[MediaStateEvent => Unit] = events.get("playerrepeated");
            private val stopTimeReachedDelegate:Option[MediaStateEvent => Unit] = events.get("stoptimereached");

            lazy val hasEvents = !(endOfMediaReachedDelegate.isEmpty
                                   && playerStartedDelegate.isEmpty
                                   && playerStoppedDelegate.isEmpty
                                   && playerRepeatedDelegate.isEmpty
                                   && stopTimeReachedDelegate.isEmpty)

            private def delegateEvent(mse:MediaStateEvent, delegate:Option[MediaStateEvent => Unit]) =
            if (!delegate.isEmpty) delegate.get.apply(mse)

            def endOfMediaReached(mse:MediaStateEvent) = delegateEvent(mse, endOfMediaReachedDelegate)

            def playerStarted(mse:MediaStateEvent) = delegateEvent(mse, playerStartedDelegate)

            def playerStopped(mse:MediaStateEvent) = delegateEvent(mse, playerStoppedDelegate)

            def playerRepeated(mse:MediaStateEvent) = delegateEvent(mse, playerRepeatedDelegate)

            def stopTimeReached(mse:MediaStateEvent) = delegateEvent(mse, stopTimeReachedDelegate)
        }
    }
}
